#ifndef SPREADSHEETUNDOCOMMAND_H
#define SPREADSHEETUNDOCOMMAND_H

// 自定义的撤销命令类 用于撤销重做命令
#include <QUndoCommand>
#include <QModelIndex>
#include "spreadsheetmodel.h"
#include <QDebug>

//基类 修改单元格命令
class SpreadsheetUndoCommand : public QUndoCommand
{
public:
    // 单个单元格修改构造函数
    SpreadsheetUndoCommand(SpreadsheetModel *model, const QModelIndex &index,
                           const QVariant &oldValue, const QVariant &newValue,
                           QUndoCommand *parent = nullptr);
    // 批量修改构造函数
    SpreadsheetUndoCommand(SpreadsheetModel *model,
                           const QMap<QModelIndex, QPair<QVariant, QVariant>>& changes,
                           QUndoCommand *parent = nullptr);
    //重写撤回重做函数
    void undo() override;// 用于撤销操作
    void redo() override;// 创建时会自动执行一次 用于执行/重做操作

public:
    //成员变量
    QModelIndex m_index;
    QVariant m_oldValue;
    QVariant m_newValue;
    QMap<QModelIndex, QPair<QVariant, QVariant>> m_changes; // 批量修改数据
    bool m_isBatch;//标记是否为批量操作
    SpreadsheetModel *m_model;
};

// 插入行命令
class InsertRowCommand : public SpreadsheetUndoCommand
{
public:
    //初始化
    InsertRowCommand(SpreadsheetModel *model, int row, QUndoCommand *parent = nullptr)
        : SpreadsheetUndoCommand(model, QModelIndex(), QVariant(), QVariant(), parent),
        m_row(row) {
        setText("Insert Row");
    }
    //撤回
    void undo() override {
        m_model->removeRow(m_row);
    }
    //重做
    void redo() override {
        // 当你 push 一个命令时，Qt 会自动调用它的 redo() 方法
        m_model->insertRow(m_row);
    }

private:
    //成员变量
    int m_row;//行
};

// 插入列命令
class InsertColumnCommand : public SpreadsheetUndoCommand
{
public:
    //初始化
    InsertColumnCommand(SpreadsheetModel *model, int column, QUndoCommand *parent = nullptr)
        : SpreadsheetUndoCommand(model, QModelIndex(), QVariant(), QVariant(), parent),
        m_column(column) {
        setText("Insert Column");
    }

    //撤回
    void undo() override {
        m_model->removeColumn(m_column);
    }

    //重做
    void redo() override {

        m_model->insertColumn(m_column);
    }

private:
    //成员变量
    int m_column;//列
};

//删除行命令
class DeleteRowCommand : public SpreadsheetUndoCommand
{
public:
    //初始化
    DeleteRowCommand(SpreadsheetModel *model, int row, QUndoCommand *parent = nullptr)
        : SpreadsheetUndoCommand(model, QModelIndex(), QVariant(), QVariant(), parent),
        m_row(row),
        m_rowData(model->getRowData(row))
    {
        setText("Delete Row");
    }

    //撤回
    void undo() override {
        m_model->insertRow(m_row);          // 恢复行
        m_model->setRowData(m_row, m_rowData); // 恢复数据
    }

    //重做
    void redo() override {
        m_model->removeRow(m_row);         // 删除行
    }

private:
    //成员变量
    int m_row;//行
    QVariantList m_rowData;  // 保存被删除行的数据
};

//删除列命令
class DeleteColumnCommand : public SpreadsheetUndoCommand
{
public:
    //初始化
    DeleteColumnCommand(SpreadsheetModel *model, int column, QUndoCommand *parent = nullptr)
        : SpreadsheetUndoCommand(model, QModelIndex(), QVariant(), QVariant(), parent),
        m_column(column),
        m_columnData(model->getColData(column))
    {
        setText("Delete Column");
    }

    //撤回
    void undo() override {
        m_model->insertColumn(m_column);          // 恢复列
        m_model->setColData(m_column, m_columnData); // 恢复数据
    }

    //重做
    void redo() override {
        m_model->removeColumn(m_column);         // 删除列
    }

private:
    //成员变量
    int m_column;//列
    QVariantList m_columnData;  // 保存被删除列的数据
};

//按列或行排序命令
class SpreadsheetSortCommand : public SpreadsheetUndoCommand {
public:
    //初始化
    SpreadsheetSortCommand(SpreadsheetModel* model,
                           int columnorRow,//行号或者列号
                           Qt::SortOrder order,
                           bool ByColorRow=true,//默认按列排序
                           QUndoCommand* parent = nullptr
                          )
        : SpreadsheetUndoCommand(model, QModelIndex(), QVariant(), QVariant(), parent),
        m_columnorRow(columnorRow), m_order(order),m_ByColorRow(ByColorRow)
    {
        //数据准备
        m_oldData = model->getAllData();//获取所有旧数据
        CaseSensitive=model->m_caseSensitiveSort;//是否大小写敏感
        m_model->beginUndoRedo();  // 禁用独立命令记录
        //保存排序结果
        if (m_ByColorRow) {
            m_model->sortColumn(m_columnorRow, m_order, CaseSensitive);// 执行排序
        } else {
            m_model->sortRow(m_columnorRow, m_order, CaseSensitive);// 执行排序
        }
        m_model->endUndoRedo();    // 恢复记录
        // 保存排序后的数据到 m_sortedData（用于重做）
        m_sortedData = m_model->getAllData();
        setText(QString("Sort ColumnorRow %1 %2")
                    .arg(columnorRow + 1)
                    .arg(order == Qt::AscendingOrder ? "↑" : "↓"));
    }

    //撤回
    void undo() override {
        m_model->beginUndoRedo();  // 禁用独立命令记录
        m_model->setAllData(m_oldData);  // 批量设置排序后数据
        m_model->endUndoRedo();    // 恢复记录
    }

    //重做
    void redo() override {
        m_model->beginUndoRedo();  // 禁用独立命令记录
        m_model->setAllData(m_sortedData);    // 恢复原始数据
        m_model->endUndoRedo();    // 恢复记录
    }

private:
    //成员变量
    int m_columnorRow;//行号或列号
    Qt::SortOrder m_order;//排序顺序
    QVector<QVector<QVariant>> m_oldData;//旧数据
    QVector<QVector<QVariant>> m_sortedData;//排序好的数据
    bool CaseSensitive;//大小写是否敏感
public:
    bool m_ByColorRow;//是否是按列排序
};

#endif // SPREADSHEETUNDOCOMMAND_H
